package com.globallogic.javatrainings.sergiiivanov.model;

import com.globallogic.javatrainings.sergiiivanov.resources.ErrorCodes;

/**
 * Stores pairs Key-Value
 * 
 * @author Sergey
 * 
 * @param <V>
 *            type of values
 */
public class MyMap<V> {
    private MyArray<String> keys;
    private MyArray<V> values;

    /**
     * Creates new empty map
     */
    public MyMap() {
        keys = new MyArray<String>(new String[0]);
        values = new MyArray<V>();
    }

    private void checkKey(String key) throws UniversityWarning {
        if (key == null) {
            throw new UniversityWarning(ErrorCodes.MAP_KEY_IS_NULL);
        }
    }

    /**
     * Returns value stored under Key
     * 
     * @param key
     *            - String key
     * @return - stored instance of V
     * @throws UniversityWarning
     *             when key not found or key == null
     * @throws UniversityFailure
     *             when code is broken (should never happen)
     */
    public V get(String key) throws UniversityWarning, UniversityFailure {
        checkKey(key);
        int index = keys.indexOf(key);
        if (index < 0) {
            throw new UniversityFailure(ErrorCodes.MAP_KEY_NOT_FOUND + key);
        }
        return values.get(index);
    }

    /**
     * Lists keys
     * 
     * @return stored keys as String[]
     */
    public String[] getKeys() {
        return keys.toArray();
    }

    /**
     * Removes pair key-value from the collection.<br>
     * not used in application yet
     * 
     * @param key
     *            String key
     * @throws UniversityWarning
     *             when key is not found or key==null
     * @throws UniversityFailure
     *             when code is broken (should never happen)
     */
    public void remove(String key) throws UniversityWarning, UniversityFailure {
        checkKey(key);
        int index = keys.indexOf(key);
        keys.remove(index);
        values.remove(index);
    }

    /**
     * Adds new value or replaces existing one
     * 
     * @param key
     *            String key, not null
     * @param value
     *            new value as instance of V
     * @throws UniversityWarning
     *             when key is null
     * @throws UniversityFailure
     *             when code is broken (should never happen)
     */
    public void set(String key, V value) throws UniversityFailure, UniversityWarning {
        checkKey(key);
        int index = keys.indexOf(key);
        if (index < 0) {
            keys.add(key);
            values.add(value);
        } else {
            values.set(index, value);
        }
    }
}
